package info.johnwheeler.gaestorage.core;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.logging.Logger;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.google.appengine.repackaged.com.google.common.util.Base64;

public class GSUtils {
    private static final Logger logger = Logger.getLogger(GSUtils.class.getName());

    public static String createPolicyDocument(String acl) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.add(Calendar.MINUTE, 20);

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        String expiration = df.format(gc.getTime());

        StringBuilder buf = new StringBuilder();
        buf.append("{\"expiration\": \"");
        buf.append(expiration);
        buf.append("\"");
        buf.append(",\"conditions\": [");
        buf.append(",{\"acl\": \"");
        buf.append(acl);
        buf.append("\"}");        
        buf.append("[\"starts-with\", \"$key\", \"\"]");
        buf.append(",[\"starts-with\", \"$success_action_redirect\", \"\"]");
        buf.append("]}");

        logger.info("policy = \n" + buf.toString());
        return Base64.encode(buf.toString().replaceAll("\n", "").getBytes());
    }

    public static String signPolicyDocument(String policyDocument, String secret) {
        try {
            Mac mac = Mac.getInstance("HmacSHA1");
            byte[] secretBytes = secret.getBytes("UTF8");
            SecretKeySpec signingKey = new SecretKeySpec(secretBytes, "HmacSHA1");
            mac.init(signingKey);
            byte[] signedSecretBytes = mac.doFinal(policyDocument.getBytes("UTF8"));
            String signature = Base64.encode(signedSecretBytes);
            return signature;
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}